<?php
class Command
{
	public $CommandLine;
	public function Command($commandLine)
	{
		$this->CommandLine=new CommandLine($commandLine);
		return $this->CommandLine->Parse();
	}
	public function ExecuteCommand()
	{
		$command=$this->CommandLine->Command;
		if(!$this->IsValidCommand($command))
		{
			$result=new Result();
			$result->ErrorCode='CmdError';
			$result->Messages[]=sprintf(L('Unknown command %1$s'),$command);
			$result->Rst=false;
			return $result;
		}
		eval("\$result=\$this->{$command}();");
		return $result;
	}
	public function IsValidCommand($command)
	{
		return in_array($command,$this->GetAvailableCommands());
	}
	public function GetAvailableCommands()
	{
		return ArrayTools::removeByValue(get_class_methods($this),array('Command','ExecuteCommand','IsValidCommand','GetAvailableCommands','GetParam','GetBoolParam'));
	}
	public function GetParam($param)
	{
		return $this->CommandLine->GetParam($param);
	}
	public function GetBoolParam($param)
	{
		return $this->CommandLine->GetBoolParam($param);
	}
	public function chgrp()
	{
		return CommandError::MakeNotAvailableError('chgrp');
	}
	public function chown()
	{
		return CommandError::MakeNotAvailableError('chown');
	}
	public function copy()
	{
		if(is_dir($this->GetParam(0)))
		{
			return $this->copydir();
		}
		$result=new Result();
		if(!@copy($this->GetParam(0),$this->GetParam(1)))
		{
			$result->ErrorCode='CopyError';
			$result->Messages[]=sprintf(L('Copy %1$s to %2$s failed'),$this->GetParam(0),$this->GetParam(1));
			$result->Rst=false;
			return $result;
		}
		else
		{
			$result->Rst=true;
			return $result;
		}
	}
	public function copydir()
	{
		$result=new Result();
		if(!is_dir($this->GetParam(0)))
		{
			return CommandError::MakeDirNoneExistError($this->GetParam(0));
		}
		if(!FileTools::CopyDir($this->GetParam(0),$this->GetParam(1)))
		{
			$result->ErrorCode='CopydirError';
			$result->Messages[]=sprintf(L('Copy %1$s to %2$s failed'),$this->GetParam(0),$this->GetParam(1));
			$result->Rst=false;
			return $result;
		}
		$result->Rst=true;
		return $result;
		
	}
	public function delete()
	{
		return $this->unlink();
	}
	public function unlink()
	{
		$result=new Result();
		if(!is_file($this->GetParam(0)))
		{
			return CommandError::MakeFileNoneExistError($this->GetParam(0));
		}
		if(!@unlink($this->GetParam(0)))
		{
			$result->ErrorCode='UnlinkError';
			$result->Messages[]=sprintf(L('Unlink %1$s failed'),$this->GetParam(0));
			$result->Rst=false;
			return $result;
		}
		else 
		{
			$result->Rst=true;
			return $result;
		}
	}
	public function diskfreespace()
	{
		return $this->disk_free_space();
	}
	public function disk_free_space()
	{
		$result=new Result();
		$result->Messages[]=L('Disk free space').' : '.FileTools::FormatSize(disk_free_space(getcwd()));
		$result->Rst=true;
		return $result;
	}
	public function disktotalspace()
	{
		return $this->disk_total_space();
	}
	public function disk_total_space()
	{
		$result=new Result();
		$result->Messages[]=L('Disk total space').' : '.FileTools::FormatSize(disk_total_space(getcwd()));
		$result->Rst=true;
		return $result;
	}
	public function fileatime()
	{
		$result=new Result();
		if(!is_file($this->GetParam(0)))
		{
			return CommandError::MakeFileNoneExistError($this->GetParam(0));
		}
		$result->Messages[]=sprintf(L('Time of last access of %1$s').' : '.date('Y-m-d h:i:s',fileatime($this->GetParam(0))),$this->GetParam(0));
		$result->Rst=true;
		return $result;

	}
	public function filectime()
	{
		$result=new Result();
		if(!is_file($this->GetParam(0)))
		{
			return CommandError::MakeFileNoneExistError($this->GetParam(0));
		}
		$result->Messages[]=sprintf(L('Time of last change of %1$s').' : '.date('Y-m-d h:i:s',filectime($this->GetParam(0))),$this->GetParam(0));
		$result->Rst=true;
		return $result;		
	}
	public function filegroup()
	{
		return CommandError::MakeNotAvailableError('filegroup');
	}
	public function filemtime()
	{
		$result=new Result();
		if(!is_file($this->GetParam(0)))
		{
			return CommandError::MakeFileNoneExistError($this->GetParam(0));
		}
		$result->Messages[]=sprintf(L('Time of last modification of %1$s').' : '.date('Y-m-d h:i:s',filemtime($this->GetParam(0))),$this->GetParam(0));
		$result->Rst=true;
		return $result;			
	}
	public function fileowner()
	{
		$result=new Result();
		if(!is_file($this->GetParam(0)))
		{
			return CommandError::MakeFileNoneExistError($this->GetParam(0));
		}
		$result->Messages[]=sprintf(L('Owner of %1$s').' : '.fileowner($this->GetParam(0)),$this->GetParam(0));
		$result->Rst=true;
		return $result;
	}
	public function fileperms()
	{
		$result=new Result();
		if(!is_file($this->GetParam(0)))
		{
			return CommandError::MakeFileNoneExistError($this->GetParam(0));
		}
		if($this->GetBoolParam('o'))
		{
			$format='oct';
		}
		$result->Messages[]=sprintf(L('Perms of %1$s').' : '.FileTools::FormatPerm(fileperms($this->GetParam(0)),$format),$this->GetParam(0));
		$result->Rst=true;
		return $result;
	}
	public function filesize()
	{
		$result=new Result();
		if(!is_file($this->GetParam(0)))
		{
			return CommandError::MakeFileNoneExistError($this->GetParam(0));
		}
		$result->Messages[]=sprintf(L('Size of %1$s').' : '.FileTools::FormatSize(filesize($this->GetParam(0))),$this->GetParam(0));
		$result->Rst=true;
		return $result;
	}
	public function dirsize()
	{
		$result=new Result();
		if(!is_dir($this->GetParam(0)))
		{
			return CommandError::MakeDirNoneExistError($this->GetParam(0));
		}
		$result->Messages[]=sprintf(L('Size of %1$s').' : '.FileTools::FormatSize(FileTools::DirSize($this->GetParam(0))),$this->GetParam(0));
		$result->Rst=true;
		return $result;
	}
	public function mkdir()
	{
		$result=new Result();
		if($this->GetParam(1))
		{
			if(!@mkdir($this->GetParam(0),$this->GetParam(1)))
			{
				$result->ErrorCode='MkdirError';
				$result->Messages[]=sprintf(L('Make directory %1$s with mode %2$s failed'),$this->GetParam(0),$this->GetParam(1));
				$result->Rst=false;
				return $result;
			}
			else
			{
				$result->Rst=true;
				return $result;
			}
		}
		else
		{
			if(!@mkdir($this->GetParam(0)))
			{
				$result->ErrorCode='MkdirError';
				$result->Messages[]=sprintf(L('Make directory %1$s failed'),$this->GetParam(0),$this->GetParam(1));
				$result->Rst=false;
				return $result;
			}
			else
			{
				$result->Rst=true;
				return $result;
			}
		}
	}
	
	public function download()
	{
		$result=new Result();
		if(!file_exists($this->GetParam(0)))
		{
			$result->ErrorCode='DownloadError';
			$result->Messages[]=sprintf(L('Download file %1$s failed'),$this->GetParam(0));
			$result->Rst=false;
			return $result;
		}
		else 
		{
			if(false===($tmp=@file_get_contents($this->GetParam(0))))
			{
				$result->ErrorCode='DownloadError';
				$result->Messages[]=sprintf(L('Download file %1$s failed'),$this->GetParam(0));
				$result->Rst=false;	
				return $result;
			}
			else
			{
				ob_clean();
				header("Content-type: application/".FileTools::FileExt($this->GetParam(0)));
				header("Content-Disposition: attachment;filename=".FileTools::FileName($this->GetParam(0)));
				header("Content-length:".filesize($this->GetParam(0)));
				print($tmp);
				exit();
			}
		}
	}
	public function rename()
	{
		$result=new Result();
		if(!@rename($this->GetParam(0),$this->GetParam(1)))
		{
			$result->ErrorCode='RenameError';
			$result->Messages[]=sprintf(L('Rename %1$s to %2$s failed'),$this->GetParam(0),$this->GetParam(1));
			$result->Rst=false;
			return $result;
		}
		else
		{
			$result->Rst=true;
			return $result;
		}
	}
	
	/********
	 * @param 0 dirname
	 * @param -r clear all files and dirs
	 */
	public function rmdir()
	{
		$result=new Result();
		if($this->GetBoolParam('r'))
		{
			if(!FileTools::RmDir($this->GetParam(0)))
			{
				$result->ErrorCode='RmdirError';
				$result->Messages[]=sprintf(L('Remove directory %1$s failed'),$this->GetParam(0));
				$result->Rst=false;
				return $result;
			}
			else 
			{
				$result->Rst=true;
				return $result;
			}
		}
		else 
		{
			if(!@rmdir($this->GetParam(0)))
			{
				$result->ErrorCode='RmdirError';
				$result->Messages[]=sprintf(L('Remove directory %1$s failed'),$this->GetParam(0));
				$result->Rst=false;
				return $result;
			}
			else 
			{
				$result->Rst=true;
				return $result;
			}
		}
	}
	
	/**
	 * Touch
	 * param 0 filename
	 * param 1 time
	 * param 2 atime
	 */
	public function touch()
	{
		$result=new Result();
		if(!$this->GetParam(1))
		{
			if(!@touch($this->GetParam(0)))
			{
				$result->ErrorCode='TouchError';
				$result->Messages[]=sprintf(L('Touch %1$s failed'),$this->GetParam(0));
				$result->Rst=false;
				return $result;
			}
			else 
			{
				$result->Rst=true;
				return $result;
			}
		}
		if(!$this->GetParam(2))
		{
			if(!@touch($this->GetParam(0),$this->GetParam(1)))
			{
				$result->ErrorCode='TouchError';
				$result->Messages[]=sprintf(L('Touch %1$s with time %2$s failed'),$this->GetParam(0),$this->GetParam(1));
				$result->Rst=false;
				return $result;
			}
			else 
			{
				$result->Rst=true;
				return $result;
			}
		}
	}
	public function cd()
	{
		return $this->chdir();
	}
	public function chdir()
	{
		$result=new Result();
		if(!@chdir($this->GetParam(0)))
		{
			$result->ErrorCode='ChdirError';
			$result->Messages[]=sprintf(L('Change to directory %1$s failed'),$this->GetParam(0));
			$result->Rst=false;
			return $result;
		}
		else 
		{
			$result->Rst=true;
			return $result;
		}
	}
	public function zip()
	{
		$result=new Result();
		if(!is_dir($this->GetParam(0)))
		{
			return CommandError::MakeDirNoneExistError($this->GetParam(0));		
		}
		$zipH=new PHPZip();
		if(!$zipH->Zip($this->GetParam(0),$this->GetParam(1)))
		{
			$result->ErrorCode='ZipError';
			$result->Messages[]=sprintf(L('Zip %1$s to %2$s failed'),$this->GetParam(0),$this->GetParam(1));
			$result->Rst=false;
			return $result;
		}
		else 
		{
			$result->Rst=true;
			return $result;
		}
	}
	public function unzip()
	{
		$result=new Result();
		$zipH=new PclZip($this->GetParam(0));
		if(!$zipH->extract($this->GetParam(1)))
		{
			$result->ErrorCode='UnzipError';
			$result->Messages[]=sprintf(L('Unzip %1$s to %2$s failed'),$this->GetParam(0),$this->GetParam(1));
			$result->Rst=false;
			return $result;
		}
		else 
		{
			$result->Rst=true;
			return $result;
		}
	}
	public function help()
	{
		$methods=get_class_methods('CommandHelp');
		$result=new Result();
		if(!$this->GetParam(0))
		{
			$result->Rst=true;
			foreach ($methods as $method)
			{
				eval("\$message=CommandHelp::{$method}();");
				$result->Messages[]="<a href=\"?command=help $method\">".$method.' : '.$message."</a>";
			}
			return $result;
		}
		if(!in_array(strtolower($this->GetParam(0)),$methods))
		{
			$result->ErrorCode='HelpNoneExist';
			$result->Messages[]=sprintf(L('Help info for %1$s not found'),$this->GetParam(0));
			$result->Rst=false;
			return $result;
		}
		eval("\$message=CommandHelp::".strtolower($this->GetParam(0))."(true);");
		$result->Messages[]=$message;
		$result->Rst=true;
		return $result;
	}
	public function cwd()
	{
		$result=new Result();
		$result->Messages[]=L('Cwd').' : '.getcwd();
		$result->Rst=true;
		return $result;
	}
	public function logout()
	{
		$this->quit();
	}
	public function quit()
	{
		Entry::Logout(false);
	}
	public function refresh()
	{
	}
	public function version()
	{
		$result=new Result();
		$result->Messages[]=L('Version').' : '.HANDLE_VERSION;
		$result->Messages[]=L('Release').' : '.HANDLE_RELEASE;
		$result->Messages[]=L('More').' : '.HANDLE_REFERER;
		$result->Rst=true;
		return $result;
	}
	public function upload()
	{
		$result=new Result();
		$source=$_FILES['file']['tmp_name'];
		$clientName=$_FILES['file']['name'];
		$filename=FileTools::FileName($clientName);
		if($this->GetParam(0))
		{
			$filename=$this->GetParam(0);
		}
		if(!file_exists($source))
		{
			$result->ErrorCode='UploadError';
			$result->Messages[]=L('File is not uploaded');
			$result->Rst=false;
			return $result;
		}
		if(!@copy($source,$filename))
		{
			$result->ErrorCode='UploadError';
			$result->Messages[]=sprintf(L('Upload %1$s to %2$s failed'),$clientName,$filename);
			$result->Rst=false;
		}
		else 
		{
			$result->Rst=true;
		}
		@unlink($source);
		return $result;
	}
	public function chmod()
	{
		$result=new Result();
		if(!@chmod($this->GetParam(0),$this->GetParam(1)))
		{
			$result->ErrorCode='ChmodError';
			$result->Messages[]=sprintf(L('Change mod of %1$s to %2$s failed'),$this->GetParam(0),$this->GetParam(1));
			$result->Rst=false;
			return false;
		}
		$result->Rst=true;
		return $result;
	}
	public function root()
	{
		$result=new Result();
		$result->Messages[]=L('Blue root').' : '.BLUE_ROOT;
		$result->Rst=true;
		return $result;
	}
}
?>